#!/usr/bin/perl

package get_feature_info;

use strict;
use warnings;

use lib 'lib';
use base 'SADI::Simple::AsyncService';

#-----------------------------------------------------------------
# SERVICE CONFIGURATION
#-----------------------------------------------------------------

use SADI::GMOD::Config qw(
    get_base_url
    get_gmod_name
    get_primary_dbxref
);

use Utils::Dbxref qw(dbxref_to_record_type);

my %config = (

    ServiceName => sprintf('get_feature_info%s', get_gmod_name() ? sprintf(' (%s)', get_gmod_name()) : ''),
    Description => 'retrieve a description of a feature by its database ID',
    InputClass => dbxref_to_record_type(get_primary_dbxref),
    OutputClass => 'http://sadiframework.org/ontologies/GMOD/service/get_feature_info.owl#OutputClass',   
    Authority => 'sadiframework.org', 
    Provider => 'ben.vvalk@gmail.com',
    URL => get_base_url . 'get_feature_info', # only required for asynchronous services

);

#-----------------------------------------------------------------
# CGI HANDLER PART
#-----------------------------------------------------------------

use Log::Log4perl;


Log::Log4perl->init('log4perl.properties');

my $service = get_feature_info->new;
$service->handle_cgi_request;

#-----------------------------------------------------------------
# SERVICE IMPLEMENTATION PART
#-----------------------------------------------------------------

use SADI::GMOD::Config qw(
    get_db_args
    get_gff_id_to_dbxref_mapping
);
use RDF::Trine::Node::Resource;
use RDF::Trine::Node::Literal;
use RDF::Trine::Statement;
use RDF::Trine::Parser;
use Bio::DB::SeqFeature::Store::Extended;
use Utils::LSRN qw(get_id_from_lsrn_record_node);
use Utils::Dbxref qw(
    id_type_to_dbxref
    get_feature_by_primary_dbxref
);

=head2 new 

 Function: create a new instance of the service
 
=cut

sub new {
    my $class = shift;
    my $self = $class->SUPER::new(%config);
    bless($self, $class);
    return $self;
}

=head2 process_it

 Function: implements the business logic of a SADI service
 Args    : $inputs - ref to an array of RDF::Trine::Node::Resource
           $input_model - an RDF::Trine::Model containing the input RDF data
           $output_model - an RDF::Trine::Model containing the output RDF data
 Returns : nothing (service output is stored in $output_model)

=cut

sub process_it {

    my ($self, $inputs, $input_model, $output_model) = @_;

    my $log = Log::Log4perl->get_logger('get_feature_info');
    my $db = Bio::DB::SeqFeature::Store::Extended->new(get_db_args, -gff_id_to_dbxref => get_gff_id_to_dbxref_mapping);
    my $parser = RDF::Trine::Parser->new('turtle');

    my $is_about = RDF::Trine::Node::Resource->new('http://semanticscience.org/resource/SIO_000332');

    foreach my $input (@$inputs) {

        next unless $input->is_resource && !$input->is_blank;
        
        $log->info(sprintf('processing input %s', $input->uri));

        my ($id_type, $id) = get_id_from_lsrn_record_node($input_model, $input);
        next unless $id_type and $id;

        my @dbnames = id_type_to_dbxref($id_type);
        next unless @dbnames;

        foreach my $dbname (@dbnames) {

            my $feature = get_feature_by_primary_dbxref($db, "$dbname:$id");
            next unless $feature;

            my $feature_node;
            if ($feature->uri) {
                $feature_node = RDF::Trine::Node::Resource->new($feature->uri);
            } else {
                $feature_node = RDF::Trine::Node::Blank->new;
            }

            my $statement = RDF::Trine::Statement->new($input, $is_about, $feature_node);
            $output_model->add_statement($statement);
            $parser->parse_into_model(undef, $feature->ttl, $output_model);

        }

    }

}

1;

__END__
